package com.mingqijia.gassafety.webserver.response.cmp;

import com.gap.basic.jackson.JsonUtil;
import com.gap.basic.utils.HttpStatus;
import io.swagger.annotations.ApiModelProperty;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import lombok.experimental.Accessors;
import org.slf4j.MDC;

import java.io.Serializable;

/**
 * Description:
 *
 * @author zhufeng
 * @since 2022/8/1
 */
@Getter
@Setter
@SuppressWarnings("ALL")
@Accessors(chain = true)
@AllArgsConstructor
@NoArgsConstructor
public class CmpCommonResponse<T> implements Serializable {

    public static final String X_TRACEID_HEADER = "Request-Id";

    /**
     * 调用是否成功标识，0：成功，-1:系统繁忙，此时请开发者稍候再试 详情见[ExceptionCode]
     */
    @ApiModelProperty(value = "响应编码:0/200-请求处理成功")
    private Integer resultCode;

    /**
     * 结果消息，如果调用成功，消息通常为空T
     */
    @ApiModelProperty(value = "提示消息")
    private String resultInfo;

    /**
     * 调用结果
     */
    @ApiModelProperty(value = "响应数据")
    private T data;

    /**
     * traceId
     */
    @ApiModelProperty(value = "调用链traceId")
    private String traceId;

    public CmpCommonResponse(Integer resultCode, String resultInfo) {
        this.resultCode = resultCode;
        this.resultInfo = resultInfo;
        this.traceId = MDC.get(X_TRACEID_HEADER);
    }

    /**
     * 调用成功-返回数据
     *
     * @param data
     * @param <T>
     * @return
     */
    public static <T> CmpCommonResponse<T> success(T data) {
        return assemble(HttpStatus.SUCCESS, "操作成功", data);
    }

    /**
     * 组装返回调用结果
     *
     * @param resultCode
     * @param resultInfo
     * @param data
     * @param <T>
     * @return
     */
    private static <T> CmpCommonResponse<T> assemble(Integer resultCode, String resultInfo, T data) {
        if (resultCode == null) {
            throw new IllegalArgumentException("resultCode不能为null");
        }

        return new CmpCommonResponse<>(resultCode, resultInfo, data, MDC.get(X_TRACEID_HEADER));
    }

    /**
     * 调用成功-返回数据和消息
     *
     * @param data
     * @param resultInfo
     * @param <T>
     * @return
     */
    public static <T> CmpCommonResponse<T> success(T data, String resultInfo) {
        return assemble(HttpStatus.SUCCESS, resultInfo, data);
    }

    /**
     * 调用失败-默认
     *
     * @param <T>
     * @return
     */
    public static <T> CmpCommonResponse<T> failure() {
        return assemble(1002, null, null);
    }

    /**
     * 调用失败-返回消息
     *
     * @param resultInfo
     * @param <T>
     * @return
     */
    public static <T> CmpCommonResponse<T> failure(int errCode, String resultInfo) {
        return assemble(errCode, resultInfo, null);
    }

    /**
     * 调用失败-返回消息
     *
     * @param resultInfo
     * @param <T>
     * @return
     */
    public static <T> CmpCommonResponse<T> failure(String resultInfo) {
        return assemble(1002, resultInfo, null);
    }

    /**
     * 调用失败-返回数据
     *
     * @param data
     * @param <T>
     * @return
     */
    public static <T> CmpCommonResponse<T> failure(T data) {
        return assemble(1002, null, data);
    }

    /**
     * 调用失败-返回消息和数据
     *
     * @param resultInfo
     * @param data
     * @param <T>
     * @return
     */
    public static <T> CmpCommonResponse<T> failure(String resultInfo, T data) {
        return assemble(1002, resultInfo, data);
    }

    /**
     * 自定义调用返回值-返回调用返回码和消息
     *
     * @param resultCode
     * @param resultInfo
     * @param <T>
     * @return
     */
    public static <T> CmpCommonResponse<T> custom(Integer resultCode, String resultInfo) {
        return assemble(resultCode, resultInfo, null);
    }

    /**
     * 自定义调用返回值-返回调用返回码、消息和数据
     *
     * @param resultCode
     * @param resultInfo
     * @param data
     * @param <T>
     * @return
     */
    public static <T> CmpCommonResponse<T> custom(Integer resultCode, String resultInfo, T data) {
        return assemble(resultCode, resultInfo, data);
    }

    /**
     * 自定义调用返回值-返回调用返回码、消息和数据
     *
     * @param resultCode
     * @param data
     * @param <T>
     * @return
     */
    public static <T> CmpCommonResponse<T> custom(Integer resultCode, T data) {
        return assemble(resultCode, null, data);
    }


    @Override
    public String toString() {
        return JsonUtil.toJson(this);
    }
}

